package codegenerate.actions;


import java.awt.Desktop;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.internal.core.JavaProject;
import org.eclipse.jdt.internal.core.PackageFragment;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleConstants;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.console.IConsoleView;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.console.MessageConsoleStream;

import codegenerate.Activator;

public class SampleAction implements IWorkbenchWindowActionDelegate {
	private IWorkbenchWindow window;
	public final static String MY_CONSOLE="GWTCodeGenerate";

	public SampleAction() {
	}

	@SuppressWarnings("restriction")
	public void run(IAction action) {
		IStructuredSelection structured = (IStructuredSelection) PlatformUI
				.getWorkbench().getActiveWorkbenchWindow()
				.getSelectionService()
				.getSelection("org.eclipse.jdt.ui.PackageExplorer");
		Object ss = structured.getFirstElement();
		if (ss instanceof PackageFragment) {
			final PackageFragment packageFragment = (PackageFragment) structured.getFirstElement();
			String selectedPackage = packageFragment.getPrimaryElement().getElementName();
			if (selectedPackage.contains("client")) {
				Shell myShell = createPropertyView(packageFragment);
				myShell.open();
			}else {
				showMessage("please select valid package which contains client package");
			}
		}else if(ss instanceof JavaProject) {
			 try {
				 //TODO
				openInDosCmd(ss);
//				 showMessageByConsole(ss);
			} catch (IOException e) {
				showMessage(e.getMessage());
			}
		} else {
			showMessage("please select valid package which contains client package");
		}
	}
	private Shell createPropertyView(@SuppressWarnings("restriction") final PackageFragment packageFragment) {
		final Shell myShell = new Shell(window.getShell());
		myShell.setText("create activity,place,remote,ui");
		myShell.setBounds(120, 120, 400, 120);
		GridLayout myLayout = new GridLayout();
		myLayout.numColumns = 2;
		myShell.setLayout(myLayout);

		GridData gridData = new GridData();
		gridData.horizontalSpan = 2;

		Label myLabel = new Label(myShell, SWT.LEFT);
		myLabel.setText("package name:");

		final Text myText = new Text(myShell, SWT.SINGLE | SWT.BORDER);
		myText.setText("input package name");
		myText.addFocusListener(new FocusListener() {
			public void focusLost(FocusEvent arg0) {
				if ("".equals(myText.getText()) || myText.getText() == null) {
					myText.setText("input package name");
				}
			}

			@Override
			public void focusGained(FocusEvent arg0) {
				if ("input package name".equals(myText.getText())) {
					myText.setText("");
				}
			}
		});
		gridData = new GridData();
		gridData.horizontalAlignment = GridData.FILL;
		gridData.grabExcessHorizontalSpace = true;
		myText.setLayoutData(gridData);

		Label myLabel2 = new Label(myShell, SWT.LEFT);
		myLabel2.setText("create init method? ");

		final Button check = new Button(myShell, SWT.CHECK);
		Button ok = new Button(myShell, SWT.BUTTON1);
		ok.setText("create");
		Button cancel = new Button(myShell, SWT.BUTTON1);
		cancel.setText("cancel");
		ok.addListener(SWT.MouseDown, new Listener() {
			public void handleEvent(Event arg0) {
				String inputName = myText.getText();
				if (!"".equals(inputName) || inputName != null) {
					boolean createInit = check.getSelection();
					try {
						createPackages(inputName, createInit, packageFragment);
					} catch (Exception e) {
						showMessage(e.getMessage());
					}
					myShell.dispose();
				}
			}
		});
		cancel.addListener(SWT.MouseDown, new Listener() {
			public void handleEvent(Event arg0) {
				myShell.dispose();
			}
		});
		return myShell;
	}
	private void showMessage(String msg){
		MessageDialog.openInformation(window.getShell(),
				"", msg);
	} 
	 private void showMessageByConsole(Object ss) throws IOException {
		@SuppressWarnings("restriction")
		String command = "cmd.exe /c mvn -f "
				+ ((JavaProject) ss).getResource().getLocation().toString()
				+ "/pom.xml gwt:run";
		Process process = Runtime.getRuntime().exec(command);
		MessageConsole myConsole = findConsole(MY_CONSOLE);
		MessageConsoleStream out = myConsole.newMessageStream();
		myConsole.activate();
//		System.setOut(new PrintStream(out));
//		System.setErr(new PrintStream(out));
		IWorkbenchPage page = window.getActivePage();
		String id = IConsoleConstants.ID_CONSOLE_VIEW;
		try {
			IConsoleView view = (IConsoleView) page.showView(id);
			view.display(myConsole);
		} catch (PartInitException e) {
		}
		out.setActivateOnWrite(true);
		BufferedReader input = new BufferedReader(
		          new InputStreamReader(process.getInputStream()));
		      BufferedReader err = new BufferedReader(
		          new InputStreamReader(process.getErrorStream()));
		      String line;
		      while ((line = input.readLine()) != null ){
		    	  out.println(line);
		    	  out.flush();
		      }  
		      input.close();
		      while ((line = err.readLine()) != null){
		    	  out.println(line);
		    	  out.flush();
		      }
		      err.close();
		      out.close();
		      try {
		    	  process.waitFor();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
	}

	private MessageConsole findConsole(String name) {
	      ConsolePlugin plugin = ConsolePlugin.getDefault();
	      IConsoleManager conMan = plugin.getConsoleManager();
	      IConsole[] existing = conMan.getConsoles();
	      for (int i = 0; i < existing.length; i++)
	         if (name.equals(existing[i].getName()))
	            return (MessageConsole) existing[i];
	      //no console found, so create a new one
	      MessageConsole myConsole = new MessageConsole(name, null);
	      conMan.addConsoles(new IConsole[]{myConsole});
	      return myConsole;
	   }

	@SuppressWarnings("restriction")
	private void createPackages(String inputName, boolean createInit,
			PackageFragment packageFragment) throws IOException,
			FileNotFoundException {
		String selectedPackage = packageFragment.getPrimaryElement().getElementName();
		if (selectedPackage.contains("client")) {
			selectedPackage = selectedPackage + "." + inputName.toLowerCase();
			createPackages(packageFragment, inputName, selectedPackage,createInit);
			try {
				packageFragment.getJavaProject().getResource().refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor()) ;
			} catch (CoreException e) {
				e.printStackTrace();
			}
		}
	}
	@SuppressWarnings("restriction")
	private void createPackages( PackageFragment packageFragment,
			String inputName, String selectedPackage, boolean createInit) {
		try {
			IPackageFragment activity=packageFragment.getPackageFragmentRoot().createPackageFragment(selectedPackage+".activity", true, null);
			
			createActivity(inputName, selectedPackage, activity,
					createInit);
			
			IPackageFragment place=packageFragment.getPackageFragmentRoot().createPackageFragment(selectedPackage+".place", true, null);
			createPlace(inputName, selectedPackage, place,
					createInit);
			IPackageFragment remote=packageFragment.getPackageFragmentRoot().createPackageFragment(selectedPackage+".remote", true, null);
			createRemoteService(inputName, selectedPackage, remote);
			IPackageFragment ui=packageFragment.getPackageFragmentRoot().createPackageFragment(selectedPackage+".ui", true, null);
			createUI(inputName, selectedPackage, ui,createInit);
			IPackageFragment action=packageFragment.getPackageFragmentRoot().createPackageFragment(selectedPackage.substring(0,selectedPackage.lastIndexOf("client"))+"server." + inputName.toLowerCase()+".action", true, null);
			createAction(selectedPackage,action,inputName);
			IPackageFragment manager=packageFragment.getPackageFragmentRoot().createPackageFragment(selectedPackage.substring(0,selectedPackage.lastIndexOf("client"))+"server." + inputName.toLowerCase()+".manager", true, null);
			createManager(selectedPackage,manager,inputName);
			
//			i=activity.getJavaProject().getProject();
//			i.refreshLocal(IResource.DEPTH_ZERO, null);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


	private void createAction(String selectedPackage, IPackageFragment pack,
			String inputName) throws IOException,
			FileNotFoundException, CoreException{
		String realPath=pack.getResource().getLocation().toString();
		File file = new File(realPath+"/" +inputName+"Action.java");
		file.createNewFile();
		BufferedWriter bw = new BufferedWriter(new FileWriter(file));
		URL url = FileLocator.find(Activator.getDefault().getBundle(), Path.ROOT, null);
		url = FileLocator.toFileURL(url);
		String action = Path.fromOSString(url.getPath()).toString()+"action.txt" ;
		BufferedReader br = new BufferedReader(new FileReader(action.replaceAll("reference:file:/", "")));
		String s5 = br.readLine();
		
		while (s5 != null) {
			s5 = s5.replaceAll("ServerPackage", selectedPackage.substring(0,selectedPackage.lastIndexOf("client")) + "server." + inputName.toLowerCase()).replaceAll("XXXX", inputName).replaceAll("zzzz", inputName.toLowerCase()).replaceAll("RemotePackage", selectedPackage);
			bw.write(s5 + "\n");
			s5 = br.readLine();
		}
		br.close();
		bw.close();
		String path=pack.getPath()+"/"+inputName + "Action.java";
		refreshPath(pack, path);
		
	}
	private void createManager(String selectedPackage, IPackageFragment pack,
			String inputName) throws IOException,
			FileNotFoundException, CoreException{
		String realPath=pack.getResource().getLocation().toString();
		File file = new File(realPath+"/" +inputName +"Manager.java");
		file.createNewFile();
		URL url = FileLocator.find(Activator.getDefault().getBundle(), Path.ROOT, null);
		url = FileLocator.toFileURL(url);
		BufferedWriter bw = new BufferedWriter(new FileWriter(file));
		String manager = Path.fromOSString(url.getPath()).toString()+"manager.txt" ;
		BufferedReader br = new BufferedReader(new FileReader(manager.replaceAll("reference:file:/", "")));
		String s5 = br.readLine();
		while (s5 != null) {
			s5 = s5.replaceAll("ServerPackage", selectedPackage.substring(0,selectedPackage.lastIndexOf("client")) + "server." + inputName.toLowerCase()).replaceAll("XXXX", inputName);
			bw.write(s5 + "\n");
			s5 = br.readLine();
		}
		br.close();
		bw.close();
		String path=pack.getPath()+"/"+inputName + "Manager.java";
		refreshPath(pack, path);
		
	}

	private void createUI(String inputName,
			String selectedPackage, IPackageFragment pack,boolean init) throws IOException,
			FileNotFoundException, CoreException {
		String realPath=pack.getResource().getLocation().toString();
		File file = new File(realPath +"/"+ inputName + "View.java");
		file.createNewFile();
		BufferedWriter bw = new BufferedWriter(new FileWriter(file));
		URL url = FileLocator.find(Activator.getDefault().getBundle(), Path.ROOT, null);
		url = FileLocator.toFileURL(url);
		String view = Path.fromOSString(url.getPath()).toString() ;
		if (init) {
			view = view + "view2.txt";
		} else {
			view = view + "view.txt";
		}
		BufferedReader br = new BufferedReader(new FileReader(view.replaceAll("reference:file:/", "")));
		String s5 = br.readLine();
		while (s5 != null) {
			s5 = s5.replaceAll("SelectedPackage", selectedPackage).replaceAll("XXXX", inputName);
			bw.write(s5 + "\n");
			s5 = br.readLine();
		}
		br.close();
		bw.close();
		file = new File(realPath + "/" + inputName + "View.ui.xml");
		file.createNewFile();
		bw = new BufferedWriter(new FileWriter(file));
		String xml = Path.fromOSString(url.getPath()).toString() + "xml.txt";
		br = new BufferedReader(new FileReader(xml.replaceAll("reference:file:/", "")));
		String s6 = br.readLine();
		while (s6 != null) {
			s6 = s6.replaceAll("SelectedPackage", selectedPackage).replaceAll("XXXX", inputName);
			bw.write(s6 + "\n");
			s6 = br.readLine();
		}
		br.close();
		bw.close();
		String path=pack.getPath()+"/"+inputName + "View.java";
		refreshPath(pack, path);
		
		path=pack.getPath()+"/"+inputName + "View.ui.xml";
		refreshPath(pack, path);
		
	}

	private void createRemoteService(String inputName,
			String selectedPackage, IPackageFragment pack) throws IOException,
			FileNotFoundException, CoreException {
		String realPath=pack.getResource().getLocation().toString();
		File file = new File(realPath +"/"+ inputName + "Service.java");
		file.createNewFile();
		BufferedWriter bw = new BufferedWriter(new FileWriter(file));
		
		URL url = FileLocator.find(Activator.getDefault().getBundle(), Path.ROOT, null);
		url = FileLocator.toFileURL(url);
		String service = Path.fromOSString(url.getPath()).toString() + "service.txt";
		BufferedReader br = new BufferedReader(new FileReader(service.replaceAll("reference:file:/", "")));
		String s3 = br.readLine();
		while (s3 != null) {
			s3 = s3.replaceAll("SelectedPackage", selectedPackage)
					.replaceAll("XXXX", inputName)
					.replaceAll("zzzz", inputName.toLowerCase());
			bw.write(s3 + "\n");
			s3 = br.readLine();
		}
		br.close();
		bw.close();
		file = new File(realPath + "/" + inputName + "ServiceAsync.java");
		file.createNewFile();
		bw = new BufferedWriter(new FileWriter(file));
		String serviceAsync = Path.fromOSString(url.getPath()).toString() + "serviceAsync.txt";
		br = new BufferedReader(new FileReader(serviceAsync.replaceAll(
				"reference:file:/", "")));
		String s4 = br.readLine();
		while (s4 != null) {
			s4 = s4.replaceAll("SelectedPackage", selectedPackage).replaceAll(
					"XXXX", inputName);
			bw.write(s4 + "\n");
			s4 = br.readLine();
		}
		br.close();
		bw.close();
		String path=pack.getPath()+"/"+inputName + "Service.java";
		refreshPath(pack, path);
		
		path=pack.getPath()+"/"+inputName + "ServiceAsync.java";
		refreshPath(pack, path);
	}

	private void createPlace(String inputName,
			String selectedPackage, IPackageFragment pack, boolean init)
			throws IOException, FileNotFoundException, CoreException {
		String realPath=pack.getResource().getLocation().toString();
		File file = new File(realPath +"/"+ inputName + "Place.java");
		file.createNewFile();
		BufferedWriter bw = new BufferedWriter(new FileWriter(file));
		URL url = FileLocator.find(Activator.getDefault().getBundle(), Path.ROOT, null);
		url = FileLocator.toFileURL(url);
		String place = Path.fromOSString(url.getPath()).toString();
		if (init) {
			place = place + "place2.txt";
		} else {
			place = place + "place.txt";
		}
		BufferedReader br = new BufferedReader(new FileReader(place.replaceAll(
				"reference:file:/", "")));
		String s2 = br.readLine();
		while (s2 != null) {
			s2 = s2.replaceAll("SelectedPackage", selectedPackage)
					.replaceAll("XXXX", inputName)
					.replaceAll("zzzz", inputName.toLowerCase());
			bw.write(s2 + "\n");
			s2 = br.readLine();
		}
		br.close();
		bw.close();
		String path=pack.getPath()+"/"+inputName + "Place.java";
		refreshPath(pack, path);
	}

	private void createActivity(String inputName,
			String selectedPackage, IPackageFragment pack, boolean init)
			throws IOException, FileNotFoundException, CoreException {
		String realPath=pack.getResource().getLocation().toString();
		File file = new File(realPath+"/"+inputName + "Activity.java");
		file.createNewFile();
		BufferedWriter bw = new BufferedWriter(new FileWriter(file));
		URL url = FileLocator.find(Activator.getDefault().getBundle(), Path.ROOT, null);
		url = FileLocator.toFileURL(url);
		String activity = Path.fromOSString(url.getPath()).toString();
		if (init) {
			activity=activity+"activity2.txt";
		} else {
			activity=activity+"activity.txt";
		}
		BufferedReader br = new BufferedReader(new FileReader(
				activity.replaceAll("reference:file:/", "")));
		String s = br.readLine();
		while (s != null) {
			s = s.replaceAll("SelectedPackage", selectedPackage)
					.replaceAll("XXXX", inputName)
					.replaceAll("zzzz", inputName.toLowerCase());
			bw.write(s + "\n");
			s = br.readLine();
		}
		br.close();
		bw.close();
		String path=pack.getPath()+"/"+inputName + "Activity.java";
		refreshPath(pack, path);
		
	}

	private void refreshPath(IPackageFragment pack, String path)
			throws CoreException {
		IProject i=pack.getJavaProject().getProject();
		path=path.replace(pack.getJavaProject().getElementName()+"/", "");
		IFile ff=i.getFile(path);
		ff.refreshLocal(IResource.DEPTH_INFINITE, null);
	}

	private void openInDosCmd(Object ss) throws IOException{
		URL url = FileLocator.find(Activator.getDefault().getBundle(), Path.ROOT, null);
		url = FileLocator.toFileURL(url);
		String bat = Path.fromOSString(url.getPath()).toString()  + "start.bat";
		File file = new File(bat);
		if(file.exists()){
			file.delete();
		}
		file.createNewFile();
		BufferedWriter bw = new BufferedWriter(new FileWriter(file));
		@SuppressWarnings("restriction")
		String command="cmd.exe /k mvn -f "+((JavaProject) ss).getResource().getLocation().toString()+"/pom.xml gwt:run";
		bw.write(command);
		bw.close();
		Desktop dt = Desktop.getDesktop();
		dt.open(file);
	}

	public void selectionChanged(IAction action, ISelection selection) {
	}

	public void dispose() {
	}

	public void init(IWorkbenchWindow window) {
		this.window = window;
	}
}
